// testRemoteThread.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

typedef HMODULE (WINAPI *GETMODULEHANDLE)(LPCTSTR);
typedef FARPROC (WINAPI *GETPROCADDRESS)(HMODULE,LPCSTR);
typedef DWORD (WINAPI *Proc_i32_v)();

struct INJLIBINFO
{
  GETMODULEHANDLE fnGetModuleHandle;
  GETPROCADDRESS fnGetProcAddress;
  LPCTSTR lpModuleName;
  LPCSTR lpProcName;
}; 

__declspec(naked)
__declspec(noinline) static DWORD WINAPI RemoteExecute(INJLIBINFO* pInfo)
{
  //if(pInfo==NULL) return -1;

  //HMODULE hModule = pInfo->fnGetModuleHandle(pInfo->lpModuleName);
  //if(hModule==NULL) return -2;

  //Proc_i32_v lpFunction = (Proc_i32_v) pInfo->fnGetProcAddress(hModule,pInfo->lpProcName);
  //if (lpFunction==NULL) return -3;

  //return lpFunction();

	_asm
	{
		push        esi  
		mov         esi,dword ptr [esp+8]
		test        esi,esi 
		jne         p1
	
		or          eax,0FFFFFFFFh 
		jmp         end
	
	p1:
		push        dword ptr [esi+8] 
		call        dword ptr [esi] 
		test        eax,eax 
		jne         p2 
	
		mov         eax,0FFFFFFFEh 
		jmp         end
	
	p2:
		push        dword ptr [esi+0Ch] 
		push        eax  
		call        dword ptr [esi+4] 
		test        eax,eax 
		jne         p3 
	
		mov         eax,0FFFFFFFDh 
		jmp         end
	
	p3:
		call        eax 
	
	end:
		pop         esi  
		ret         4    
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	INJLIBINFO info;
	info.fnGetModuleHandle = GetModuleHandleW;
	info.fnGetProcAddress = GetProcAddress;
	info.lpModuleName = L"kernel32.dll";
	info.lpProcName = "GetProcessHeap";
	
	RemoteExecute(&info);

	return 0;
}

